package com.cait.dutyfree.dataaccess.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.cait.dutyfree.action.impl.LoginAction;
import com.cait.dutyfree.dataaccess.UserServiceDAO;
import com.cait.dutyfree.exception.DutyFreeException;
import com.cait.dutyfree.pojo.LoginDetail;
import com.cait.dutyfree.pojo.LoginUser;
import com.cait.dutyfree.pojo.UserEvent;
import com.cait.dutyfree.security.Password;

public class CusServiceDaoImpl extends HibernateDaoSupport  implements UserServiceDAO {

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#userAuthentication(java.lang.String, java.lang.String)
		 */
		
		private static final Logger logger = Logger.getLogger(LoginAction.class);
		
		public String userAuthentication(String username, String password) throws Exception {
			
			LoginUser user = null;
			DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
			criteria.add(Restrictions.eq("username", username));

			Password p = new Password("onlykalu");
			
			try{
				@SuppressWarnings("rawtypes")
				List users = getHibernateTemplate().findByCriteria(criteria);
				if ((users != null) && (users.size() > 0)) {
					user = (LoginUser) users.get(0);
					//System.out.println(user.getPassword()+"gettt"+p.encrypt(password)+""+users.get(0)+" "+user.getUsername());
					if(user.getFailedLoginAttempts() > 3) {
						logger.warn("Blocked user attempt "+username);
						return "block";
					}
		        	if(user.getPassword().equals(p.encrypt(password))){
		        		
		        		if(user.getStatus() == -1) return "pending";
		        		if(user.getStatus() == 1) return "block";
		        		if(user.getStatus() == 2) return "deactivate";
		        		resetFailLoginAttempts(user);
		        		return "sucess";
		        	}else{
		        		//System.out.println(user.getPassword()+"fail"+p.encrypt(password));
		        		increaseFailLoginAttempts(user);
		    			return "fail";
		        	}
				}
			}catch(Exception e){
				System.out.println(e);
				return "error";
			}
			return "fail";
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#addUser(com.cait.dutyfree.pojo.LoginUser)
		 */
		public boolean addUser(LoginUser user) throws Exception {
			
			try{
				if(!isUserAvailable(user.getUsername())){
					getHibernateTemplate().save(user);
					getHibernateTemplate().flush();
					return true;
				}else{
					logger.warn("user already available "+user.getUsername());
					throw new DutyFreeException(1001, new Exception("User Already Available"));
				}
			}catch (Exception e) {
				throw new DutyFreeException(1002, e);
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#updateUser(com.cait.dutyfree.pojo.LoginUser)
		 */
		public boolean updateUser(LoginUser user) throws Exception {
			try{
				if(isUserAvailable(user.getUsername())){
					getHibernateTemplate().merge(user);
					getHibernateTemplate().flush();
					return true;
				}else{
					logger.warn("user not available "+user.getUsername());
					throw new DutyFreeException(1002, new Exception("User not available"));
				}
			}catch (Exception e) {
				throw new DutyFreeException(1002, e);
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#resetFailLoginAttempts(com.cait.dutyfree.pojo.LoginUser)
		 */
		public String resetFailLoginAttempts(LoginUser user) throws Exception {
			// TODO Auto-generated method stub
			return null;
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getUsers()
		 */
		public ArrayList<LoginUser> getUsers() throws Exception {
			try{
				ArrayList<LoginUser> users = new ArrayList<LoginUser>();
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
				@SuppressWarnings("rawtypes")
				List userList = getHibernateTemplate().findByCriteria(criteria);
				if ((userList != null) && (userList.size() > 0)) {
					for(int i = 0; i < userList.size(); i++){
						users.add((LoginUser) userList.get(i));
					}
					return users;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch all users ");
				throw new DutyFreeException(1003, new Exception("During fetch all users"));
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getLockedUsers()
		 */
		public ArrayList<LoginUser> getLockedUsers() throws Exception {
			try{
				ArrayList<LoginUser> users = new ArrayList<LoginUser>();
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
				criteria.add(Restrictions.eq("failedLoginAttempts", 4));
				@SuppressWarnings("rawtypes")
				List userList = getHibernateTemplate().findByCriteria(criteria);
				if ((userList != null) && (userList.size() > 0)) {
					for(int i = 0; i < userList.size(); i++){
						users.add((LoginUser) userList.get(i));
					}
					return users;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch locked users ");
				throw new DutyFreeException(1004, new Exception("During fetch locked users"));
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getUser(java.lang.String)
		 */
		public LoginUser getUser(String username) throws Exception {
			try{
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
				criteria.add(Restrictions.eq("username", username));
				@SuppressWarnings("rawtypes")
				List users = getHibernateTemplate().findByCriteria(criteria);
				LoginUser user;
				if ((users != null) && (users.size() > 0)) {
					user = (LoginUser) users.get(0);
					return user;
				}
				return null;	
			}catch (Exception e) {
				logger.warn("During fetch user by username ");
				throw new DutyFreeException(1005, new Exception("During fetch user by username"));
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getUser(int)
		 */
		public LoginUser getUser(int userID) throws Exception {
			try{
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
				criteria.add(Restrictions.eq("userId", userID));
				@SuppressWarnings("rawtypes")
				List users = getHibernateTemplate().findByCriteria(criteria);
				LoginUser user;
				if ((users != null) && (users.size() > 0)) {
					user = (LoginUser) users.get(0);
					return user;
				}
				return null;	
			}catch (Exception e) {
				logger.warn("During fetch user by userid ");
				throw new DutyFreeException(1005, new Exception("During fetch user by userid"));
			}
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#updateLastLoginDetails(com.cait.dutyfree.pojo.LoginUser)
		 */
		public boolean updateLastLoginDetails(LoginUser user) throws Exception {
			// TODO Auto-generated method stub
			return false;
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getUserByName(java.lang.String)
		 */
		public LoginUser getUserByName(String name) throws Exception {
			// TODO Auto-generated method stub
			return null;
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#addLoginDetail(com.cait.dutyfree.pojo.LoginDetail)
		 */
		public String addLoginDetail(LoginDetail detail) throws Exception {
			// TODO Auto-generated method stub
			return null;
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getDetails(com.cait.dutyfree.pojo.LoginUser)
		 */
		public ArrayList<LoginDetail> getDetails(LoginUser user) throws Exception {
			
			try{
				ArrayList<LoginDetail> logs = new ArrayList<LoginDetail>();
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginDetail.class);
				criteria.add(Restrictions.eq("user", user));
				@SuppressWarnings("rawtypes")
				List list = getHibernateTemplate().findByCriteria(criteria);
				if ((list != null) && (list.size() > 0)) {
					for(int i = 0; i < list.size(); i++){
						logs.add((LoginDetail) list.get(i));
					}
					return logs;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch log details by user ");
				throw new DutyFreeException(1004, new Exception("During fetch log details by user "));
			}

		}
		
		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getDetails(com.cait.dutyfree.pojo.LoginUser, int, int)
		 */
		public ArrayList<LoginDetail> getDetails(LoginUser user, int pageSize, int pageNo) throws Exception {
			
			try{
				ArrayList<LoginDetail> logs = new ArrayList<LoginDetail>();
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginDetail.class);
				criteria.add(Restrictions.eq("user", user));
				//criteria.addOrder(Order.asc("lodID"));
				criteria.getExecutableCriteria(getSession())
											.setFirstResult(pageSize * (pageNo - 1));
				getHibernateTemplate().setMaxResults(pageSize);
				@SuppressWarnings("rawtypes")
				List list = getHibernateTemplate().findByCriteria(criteria);
				getHibernateTemplate().setMaxResults(0);
				if ((list != null) && (list.size() > 0)) {
					for(int i = 0; i < list.size(); i++){
						logs.add((LoginDetail) list.get(i));
					}
					return logs;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch log details by user with paging");
				throw new DutyFreeException(1004, new Exception("During fetch log details by user with paging"));
			}

		}

		public boolean isUserAvailable(String userName) throws Exception{
			
			try{
				DetachedCriteria criteria = DetachedCriteria.forClass(LoginUser.class);
				criteria.add(Restrictions.eq("username", userName));
				@SuppressWarnings("rawtypes")
				List users = getHibernateTemplate().findByCriteria(criteria);
				if ((users != null) && (users.size() > 0)) {
		       		return true;
				}
				return false;
			}catch (Exception e) {
				throw e;
				// TODO: handle exception
			}
		}
		
		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#addUserEvent(com.cait.dutyfree.pojo.UserEvent)
		 */
		public String addUserEvent(UserEvent event) throws Exception {
			// TODO Auto-generated method stub
			return null;
		}

		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getEvents(com.cait.dutyfree.pojo.LoginUser)
		 */
		public ArrayList<UserEvent> getEvents(LoginUser user) throws Exception {

			try{
				ArrayList<UserEvent> events = new ArrayList<UserEvent>();
				DetachedCriteria criteria = DetachedCriteria.forClass(UserEvent.class);
				criteria.add(Restrictions.eq("user", user));
				@SuppressWarnings("rawtypes")
				List list = getHibernateTemplate().findByCriteria(criteria);
				if ((list != null) && (list.size() > 0)) {
					for(int i = 0; i < list.size(); i++){
						events.add((UserEvent) list.get(i));
					}
					return events;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch user events ");
				throw new DutyFreeException(1004, new Exception("During fetch user events "));
			}
		}

		
		/* (non-Javadoc)
		 * @see com.cait.dutyfree.dataaccess.UserServiceDAO#getAllEvents()
		 */
		public ArrayList<UserEvent> getAllEvents() throws Exception {
			try{
				ArrayList<UserEvent> events = new ArrayList<UserEvent>();
				DetachedCriteria criteria = DetachedCriteria.forClass(UserEvent.class);
				@SuppressWarnings("rawtypes")
				List list = getHibernateTemplate().findByCriteria(criteria);
				if ((list != null) && (list.size() > 0)) {
					for(int i = 0; i < list.size(); i++){
						events.add((UserEvent) list.get(i));
					}
					return events;
				}
				return null;
			}catch (Exception e) {
				logger.warn("During fetch user events ");
				throw new DutyFreeException(1004, new Exception("During fetch user events "));
			}
		}

		private boolean increaseFailLoginAttempts(LoginUser user){
			
			user.setFailedLoginAttempts( (user.getFailedLoginAttempts() + 1) );
			try{
				getHibernateTemplate().update(user);
				getHibernateTemplate().flush();
				return true;
			}catch (Exception e) {
				return false;
			}
		}



	}

